<?php

/*
 * Created on 16/02/2009
 *
 * To change the template for this generated file go to
 * Window - Preferences - PHPeclipse - PHP - Code Templates
 */
class FixtureGenerator {

	var $debug = false;
	
    function generatePlayEveryConferenceOnce() {
        global $season, $teams;
        if ($this->debug) {
            echo "<pre>\n";
        }
        if ($season->hasConferences) {
            uasort($teams->teams, "conferenceSort");
            $lastConference = false;
            $conferenceTeams = array ();
            foreach ($teams->teams as $team) {
                if (0 == strcmp($team->conference, $lastConference)) {
                    array_push($conferenceTeams, $team);
                } else {
                    if (count($conferenceTeams) > 0) {
                        $this->generateDraw($conferenceTeams);
                    }
                    $lastConference = $team->conference;
                    $conferenceTeams = array ();
                    array_push($conferenceTeams, $team);
                }
            }
            if (count($conferenceTeams) > 0) {
                $this->generateDraw($conferenceTeams);
            }
        } else {
            $this->generateDraw($teams->teams);
        }
        if ($this->debug) {
            echo "\n</pre>";
        }
    }
    /**
     * Checks to see if the teams have already played each other
     */
    function alreadyPlayed(& $rounds, & $home, & $away) {
        foreach ($rounds as $round) {
            foreach ($round as $fixture) {
                if (($fixture->homeTeam->id == $home->id && $fixture->awayTeam->id == $away->id) || ($fixture->awayTeam->id == $home->id && $fixture->homeTeam->id == $away->id)) {
                    return true;
                }
            }
        }
        return false;
    }

    /*
     * Must be an even number of teams
     */
    function makeDraw(& $drawTeams, $round, & $rounds, & $thisRound, $depth = 0) {
        global $season;
        $this->showTeams($drawTeams);
        if (count($drawTeams) > 1) {
            $home = array_shift($drawTeams);
            $testedTeams = array ();
            while (count($drawTeams) > 0) {
                $away = array_shift($drawTeams);
                if (!$this->alreadyPlayed($rounds, $home, $away)) {
                    $rc = $this->makeDraw(array_merge($testedTeams, $drawTeams), $round, $rounds, $thisRound, $depth +1);
                    if ($rc) {
                        $fix = new Fixture(0, $season, $round, $home, $away);
                        array_push($thisRound, $fix);
                        return true;
                    }
                }
                array_push($testedTeams, $away);
            }
            $drawTeams = $testedTeams;
            array_unshift($drawTeams, $home);
            return false;
        }
        return true;
    }

    /**
     * Not perfect. Sometimes the draw fails. Untested for uneven conferences
     */
    function generateDraw($drawTeams) {
        global $season;
	
		$this->showTeams($drawTeams, "Initial Teams");
        $countTeams = count($drawTeams);
        $numRounds = $countTeams -1;
        $fixtures = array ();
        $bye = false;

        if (($countTeams % 2) == 1) {
            $numRounds += 1;
            $bye = true;
        }

        shuffle($drawTeams);
        for ($i = 0; $i < $numRounds; $i++) {
            $newDrawTeams = array ();
            $keys = array_keys($drawTeams);
            for ($j = 0; $j < count($keys); $j++) {
                if ($bye && ($j == $i)) {
                    continue;
                }
                array_push($newDrawTeams, $drawTeams[$keys[$j]]);
            }
            $thisRound = array ();
            shuffle($newDrawTeams);
            $c = 5;
            $madeDraw = false;
            while ($c > 0) {
                $c = -1;
                $rc = $this->makeDraw($newDrawTeams, (1 + $i), $fixtures, $thisRound);
                if ($rc) {
                    $fixtures[$i] = $thisRound;
                    $madeDraw = true;
                    $this->showFixtures($thisRound);
                    break;
                }
            }
            if (!$madeDraw) {
                echo "<br />\n<h2>Unable to make draw</h2><br />\n";
                print_r($fixtures);
                return;
            }
        }
        $this->save($numRounds, $fixtures);

    }
    
    /**
     * Saves the fixtures
     */
    function save($numRounds, $fixtures) {
    	if ($this->debug) {
    	    return;
    	}
        global $season;
		$frd = new FixtureRoundDao();
		$rounds = $frd->findFixtureRounds($season->id);
        for ($i = 0; $i < $numRounds; $i++) {
            $rdNum = $i +1;
            if (!isset ($rounds[$rdNum])) {
                $fr = new FixtureRound();
                $fr->init($season->id, $rdNum, $rdNum);
                $rounds[$rdNum] = $fr;
            }
            $thisRound = $fixtures[$i];
            foreach ($thisRound as $fixture) {
                addFixture($season, $rdNum, $fixture->homeTeam->id, $fixture->awayTeam->id);
            }
        }
        $frd->save($rounds);
    }
    
    /**
     * Lists all the teams and their keys in the array
     */
    function showFixtures($fixtures, $label = "Fixtures", $depth = 0) {
        if ($this->debug) {
        	$this->tab($depth);
            echo "$label:\n";
            foreach($fixtures as $fixture) {
                $home = $fixture->homeTeam;
                $away = $fixture->awayTeam;
	        	$this->tab($depth);
                echo "$home->name vs $away->name\n";
            }
            echo "\n";
        }
    }
    
    /**
     * Lists all the teams and their keys in the array
     */
    function showTeams($teams, $label = "Teams", $depth = 0) {
        if ($this->debug) {
        	$this->tab($depth);
            echo "$label: ";
            $keys = array_keys($teams);
            $first = true;
            foreach($keys as $key) {
                $team = $teams[$key];
                if (!$first) {
                    echo ", ";
                }
                $first = false;
                echo "$team->name[$key]";
            }
            echo "\n";
        }
    }
    
    /**
     * Adds one tab for each depth
     */
    function tab($depth = 0) {
        if ($this->debug) {
	        for ($i = 0; $i < $depth; $i++) {
	            echo "\t";
	        }
        }
        
        
    }

}
?>
